<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
//    <param name="wmode" value="Opaque">

    <title>JS打字小游戏</title>
    <style>
        body {
            padding: 0;
            margin: 0;
        }

        #gameStage {
            width: 100%;
            height:780px;
            background-color: aquamarine;
            z-index:1;
        }

        #menu{
            width: 600px;
            height:600px;
            margin:0 auto;
            background-color: dodgerblue;
            visibility:hidden;
            position: relative;
            z-index:5555;
        }

        .display{
            font-size:32px;
            color:red;
        }
        .button{
            width:100px ;
            height:30px;
            margin:60px 250px;
        }

    </style>
</head>
<body>
<div id="gameStage">
    <a  class="display">score:  <span id="score" >0</span></a><br>
    <a  class="display" style="color:green" > life: <span id="life" >10</span></a>
    <div id="menu">
        <button class="button" onmouseup=director.replayGame()><strong>重新开始</strong></button>
        <button  class="button" id="stop" onmouseup =director.stopGame()><strong>继续游戏</strong></button>
        <button  class="button" onmouseup =director.exitGame()><strong>退出游戏</strong></button>
    </div>
</div>
<script>
  /**
   * 字母
   * @param id
   * @param alphabet
   * @param posX
   * @param posY
   * @param size
   * @constructor
   */
  function Word(id, alphabet, posX, posY, size) {

    //初始化数据
    this.id = id || '';
    this.alphabet = alphabet || 'a';
    this.posX = posX || 0;
    this.posY = posY || 0;
    this.size = size || 64;


    // 新建
    this.create = function () {
      var str = '<span class="word" id="alphabet-' + this.id + '">' + this.alphabet + '</span>';
      var gameStage = document.getElementById('gameStage');
      gameStage.innerHTML += str;

      var divNode = document.getElementById('alphabet-' + this.id);
      divNode.style.position = 'absolute';
      divNode.style.fontSize = this.size + 'px';
      divNode.style.left = this.posX + 'px';
      divNode.style.top = this.posY + 'px';

    };

    // 重置.
    this.reset = function () {
      var divNode = document.getElementById('alphabet-' + this.id);
      divNode.style.display = 'none';
      this.moveTo(0, 0);
    };

    // 移动到指定点
    this.moveTo = function (posX, posY) {
      this.posX = posX;
      this.posY = posY;

      var divNode = document.getElementById('alphabet-' + this.id);
      divNode.style.left = posX + 'px';
      divNode.style.top = posY + 'px';
    };

  }

  /**
   * 导演类
   */
  var director = {
      alphabets: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
      flag:0,
      nodes: new Array(),

      /**
       * 逐帧运行
       */
      runFrame: function () {

          //更新已经产生所有点的坐标
          for (var index in this.nodes) {
              var node = this.nodes[index];
              if (node) {
                  node.moveTo(node.posX, node.posY + 5);
              }
          }

          //随机产生字母
          var r = Math.floor(Math.random() * this.alphabets.length);
          var w = new Word(new Date().getTime(), this.alphabets[r]);

          w.create();
          this.nodes.push(w);

          var posX = Math.floor(Math.random() * window.innerWidth);
          if (posX < 50) {
              posX = 100;
          }
          if (posX >= window.innerWidth - 100) {
              posX = window.innerWidth - 100;
          }
          w.moveTo(posX, 0);
      },

      /**
       * 开始游戏
       */
      start: function () {
          var _this = this;
          //监听键盘事件
          document.onkeydown = function () {
              var alphabet = String.fromCharCode(event.keyCode); //获取键盘敲中的字母
              console.log(alphabet);
              if(alphabet==' '){
                  _this.stopGame();
              }
              for (var i = 0, len = _this.nodes.length; i < len; i++) {
                  if (!_this.nodes[i]) {
                      continue;
                  }
                  if (alphabet === _this.nodes[i].alphabet) {
                      _this.nodes[i].reset();
                      scoreCounter.incScore();
                      _this.nodes[i] = null;
              }
              document.getElementById('score').innerHTML=scoreCounter.getScore();
          }
      };

  //游戏主循环
          _this.startGame();
  },

      /*开始游戏循环 */
      startGame:function(){
          var _this=this;
      sh= setInterval(function () {
          _this.runFrame();
          _this.border();
      }, 50);
  },

      /*重新开始游戏*/
   replayGame: function(){
       var _this=this;
      clearInterval(sh);
       for (var i = 0, len = _this.nodes.length; i < len; i++)
           _this.nodes[i].reset();
       _this.nodes.splice(0,_this.nodes.length);
       _this.nodes=[];
       document.getElementById("gameStage").disabled = true;
       document.getElementById('menu').style.visibility="hidden";
       _this.startGame();
       _this.flag=0;
  },

      /*暂停、继续*/
  stopGame:function(){
      var _this=this;
       if(_this.flag==0) {
           if(scoreCounter.life<=0) {
               document.getElementById('stop').disabled=true;
           }
           document.getElementById('menu').style.visibility="visible";
           clearTimeout(setInterval(0) - 1);
           _this.flag=1;
       }else {
           document.getElementById('menu').style.visibility="hidden";
           _this.startGame();
           _this.flag=0;
       }
  },

      /*退出*/
      exitGame:function(){
       var _this=this;
          _this.nodes.splice(0,_this.nodes.length);
          window.close();
      },

      /*出界判断*/
      border:function(){
          var _this=this;
         // webHeight=window.screen.availHeight;
          for (var index in _this.nodes){
              var node = this.nodes[index];
              if (!node) {
                  continue;
              }
              if(node.posY>750 ){
                  node.reset();
                  scoreCounter.lessLife();
                  document.getElementById('life').innerHTML=scoreCounter.getLife();
              }
              if(scoreCounter.getLife()<=0) {
                  //alert("GameOver");
                  _this.stopGame();
              }
          }
      }


};


  /**
   * 计分器
   */
  var scoreCounter = {
    score: 0,
      life: 10,
    incScore: function () {
      this.score++;
    },
    getScore: function () {
      return this.score;
    },

    addLife : function(){
        this.life++;
    },
    lessLife:function(){
        this.life--;

    },
    getLife:function(){
       return this.life;
    }
  };


  director.start();


</script>
</body>
</html>